<script setup lang="ts">
import Cherry from "cherry-markdown/dist/cherry-markdown.core";
import "cherry-markdown/dist/cherry-markdown.css"
import {onMounted, ref} from "vue";
import {articleApi} from "@/api/blog/articleApi.ts";
import {MessagePlugin, UploadProps} from "tdesign-vue-next";
import {fileApi} from "@/api/blog/fileApi.ts";
import {categoryApi} from "@/api/blog/categoryApi.ts";
import {getToken} from "@/utils/auth.ts";
import day from "@/utils/day.ts";

const md = ref<Cherry>()
const article = ref({} as Article)
const categoryList = ref([
    {
      label: '默认分类',
      value: 0
    }
])
const visible = ref(false)
// 文件上传信息
const files = ref<UploadProps['value']>([
  {
    name: '默认文件',
    url: 'https://img.mikufufu.com/image/1.webp',
    status: 'success',
    size: 164.37 * 1024,
    // 上传日期，如果接口返回的字段包含 uploadTime，则会以接口返回的为准，默认使用本地电脑时间。
    // 如果希望使用接口返回的上传日期，但是接口字段名不是 uploadTime，则可以使用函数 formatResponse 格式化接口数据
    uploadTime: day(new Date()).format('YYYY-MM-DD'),
  },
])
onMounted(()=>{
  // 初始化编辑器
  md.value = new Cherry({
    id: 'md-edit',
    value: '## hello world',
    // 这里用来监听cherry-markdown的change事件 也就是当markdown内容发生变化时触发
    fileUpload: upload,
    toolbars: {
      // 定义顶部工具栏
      toolbar: [
        'undo', 'redo', '|',
        // 把字体样式类按钮都放在加粗按钮下面
        'bold', 'italic', 'underline', 'strikethrough', 'sub', 'sup', 'ruby',
        'color', 'size', '|', 'header', 'list', 'panel', '|',
        // 把插入类按钮都放在插入按钮下面
        {insert: ['image', 'audio', 'video', 'link', 'hr', 'br', 'code', 'formula', 'toc', 'table', 'drawIo']},
        'graph'
      ],
      // 定义侧边栏，默认为空
      sidebar: ['theme', 'mobilePreview', 'copy'],
      // 定义顶部右侧工具栏，默认为空
      // toolbarRight: ['fullScreen', 'export'],
      // 定义选中文字时弹出的“悬浮工具栏”，默认为 ['bold', 'italic', 'underline', 'strikethrough', 'sub', 'sup', 'quote', '|', 'size', 'color']
      bubble: ['bold', 'italic', 'underline', 'strikethrough', 'sub', 'sup', 'ruby', '|', 'color','size',],
      // 定义光标出现在行首位置时出现的“提示工具栏”，默认为 ['h1', 'h2', 'h3', '|', 'checklist', 'quote', 'table', 'code']
      float: ['table', 'code', 'graph'],
    },
  })
  categoryApi.getCategoryList().then(res=>{
    let list:  CategoryVO[] = res.data
    categoryList.value = list.map(item=>{
      return {
        label: item.categoryName,
        value: item.id! //  这里的!  表示这个值一定有值
      }
    })
  })
})
const getMarkdown = () => {
  if (md.value){
    return md.value.getMarkdown()
  }
  return ''
}
function addArticle() {
  article.value.articleContent  = getMarkdown()
  articleApi.addArticle(article.value).then(res => {
    if (res.code !== 200){
      MessagePlugin.error(res.msg)
      visible.value=false
      return
    }
    MessagePlugin.success(res.msg)
    visible.value=false
  })
}
function upload(file: File,
                    /**
                     * @param params.name 回填的alt信息
                     * @param params.poster 封面图片地址（视频的场景下生效）
                     * @param params.isBorder 是否有边框样式（图片场景下生效）
                     * @param params.isShadow 是否有阴影样式（图片场景下生效）
                     * @param params.isRadius 是否有圆角样式（图片场景下生效）
                     * @param params.width 设置宽度，可以是像素、也可以是百分比（图片、视频场景下生效）
                     * @param params.height 设置高度，可以是像素、也可以是百分比（图片、视频场景下生效）
                     */
                    callback: (url: string, params?: {name?: string, poster?: string, isBorder?: boolean, isShadow?: boolean, isRadius?: boolean; width?: string, height?: string}
                    ) => void) {
  if (file.size / 1024 / 1024 > 20) {
    MessagePlugin.warning('上传的文件不能大于20M');
    return
  }
  const formData = new FormData()
  formData.append('file', file)
  fileApi.uploadImage(formData).then((res) => {
    let imageVO :ImageVO = res.data
    // 如果上传的是图片
    callback(imageVO.url, {
      name: imageVO.name,
      isBorder: true, // 是否显示边框，默认false
      isShadow: true, // 是否显示阴影，默认false
      isRadius: true, // 是否显示圆角，默认false
    })
  }).catch((err) => {
    console.log(err)
  })
}
// res.url 图片地址；res.uploadTime 文件上传时间；res.error 上传失败的原因
function formatResponse (res: any) {
  if (res.code === 200) {
    res.status = 'success'
    res.name  = res.data.name
    res.url = res.data.url
    res.uploadTime = day(new Date()).format('YYYY-MM-DD')
    article.value.imgUrl = res.data.url
    return res
  }else {
    res.status = 'error'
    res.error = res.msg
  }
}
</script>

<template>
  <div class="md">
    <t-card>
      <div class="md-header">
        <!-- 标题  maxlength="10"是限制最大长度 -->
        <t-input
            v-model="article.title"
            :maxlength="10"
            clearable
            align="center"
            show-limit-number
            placeholder="请输入标题, 最多10个字"
        />
        <t-button theme="primary" @click="visible=true">发布文章</t-button>
      </div>
    </t-card>
    <div id="md-edit"></div>
    <t-dialog
        v-model:visible="visible"
        header="发布文章"
        width="40%"
        :confirm-on-enter="true"
        :on-cancel="() => {article={} as Article;visible=false}"
        :on-close="() => {article={} as Article;visible=false}"
        :on-confirm="addArticle"
    >
      <t-space direction="vertical" style="width: 100%">
        <t-tree-select v-model="article.categoryId" :data="categoryList" placeholder="请选择文章分类" />
        <t-upload
            v-model="files"
            theme="image"
            :abridge-name="[10, 8]"
            :format-response="formatResponse"
            draggable
            action="/api/files/uploadImage"
            :headers="{Authorization:getToken()}"
        />
        <t-input v-model="article.articleOverview" placeholder="请输入文章摘要" />
      </t-space>
    </t-dialog>
  </div>
</template>

<style scoped lang="less">
.md {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.md-header {
  display: flex;
  justify-content: flex-end;
  gap: 14px;
}
#md-edit  {
  width: 100%;
  height: calc(100% - 40px);
  margin-top: 20px;
}
</style>
